import pandas as pd
import numpy as np
import os
import logging
import json
import re
from datetime import datetime
from collections import Counter, defaultdict
import matplotlib.pyplot as plt
from wordcloud import WordCloud
import networkx as nx
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[logging.FileHandler("prevention_generator.log"), logging.StreamHandler()]
)
logger = logging.getLogger("prevention_generator")

class PreventionGenerator:
    """品牌危机预防机制生成器"""
    
    def __init__(self, brand_name=None, evaluation_results=None):
        """
        初始化预防机制生成器
        
        Args:
            brand_name: 品牌名称
            evaluation_results: 评估结果（可选，字典格式）
        """
        self.brand_name = brand_name
        self.evaluation_results = evaluation_results
        self.crisis_data = None
        self.failure_cases = []
    
    def generate_mock_evaluation_results(self):
        """
        生成模拟评估结果用于测试和演示
        
        Returns:
            dict: 模拟的评估结果
        """
        logger.info("正在生成模拟评估结果")
        
        # 随机生成评分（1-5的范围内）
        response_speed_score = round(np.random.uniform(2, 4.5), 1)
        transparency_score = round(np.random.uniform(2, 4.5), 1)
        image_protection_score = round(np.random.uniform(2, 4.5), 1)
        
        # 计算综合得分
        comprehensive_score = round((response_speed_score * 0.3 + transparency_score * 0.3 + image_protection_score * 0.4), 1)
        
        # 生成总体评估
        overall_assessment = ""
        if comprehensive_score >= 4.5:
            overall_assessment = "优秀"
        elif comprehensive_score >= 3.5:
            overall_assessment = "良好"
        elif comprehensive_score >= 2.5:
            overall_assessment = "一般"
        elif comprehensive_score >= 1.5:
            overall_assessment = "较差"
        else:
            overall_assessment = "很差"
        
        # 生成各项建议
        if response_speed_score >= 4:
            response_recommendation = f"{self.brand_name}响应速度良好，基本控制了危机扩散"
        elif response_speed_score >= 3:
            response_recommendation = f"{self.brand_name}响应速度一般，对危机控制有一定延迟"
        else:
            response_recommendation = f"{self.brand_name}响应速度较慢，建议优化危机响应流程"
        
        if transparency_score >= 4:
            transparency_recommendation = f"{self.brand_name}沟通透明度高，公开了危机详情并承担责任"
        elif transparency_score >= 3:
            transparency_recommendation = f"{self.brand_name}沟通透明度良好，但可以提供更多细节和后续措施"
        else:
            transparency_recommendation = f"{self.brand_name}沟通透明度一般，建议提供更多危机细节并说明解决方案"
        
        if image_protection_score >= 4:
            image_recommendation = f"{self.brand_name}形象保护效果良好，危机后品牌形象有所提升"
        elif image_protection_score >= 3:
            image_recommendation = f"{self.brand_name}形象保护效果一般，危机后品牌形象基本恢复"
        else:
            image_recommendation = f"{self.brand_name}形象保护效果较差，建议加强后续公关措施"
        
        # 构建评估结果字典
        mock_results = {
            '综合得分': {
                '评分': comprehensive_score,
                '建议': '综合以下各项建议'
            },
            '响应速度': {
                '评分': response_speed_score,
                '建议': response_recommendation
            },
            '沟通透明度': {
                '评分': transparency_score,
                '建议': transparency_recommendation
            },
            '品牌形象保护': {
                '评分': image_protection_score,
                '建议': image_recommendation
            },
            '总体评估': {
                '评分': overall_assessment,
                '建议': f"{self.brand_name}危机处理整体表现{overall_assessment}，综合得分为{comprehensive_score}分（满分5分）"
            }
        }
        
        logger.info("已生成模拟评估结果")
        return mock_results
    
    def generate_mock_crisis_data(self, data_points=50):
        """
        生成模拟危机数据用于测试和演示
        
        Args:
            data_points: 要生成的数据点数量
            
        Returns:
            DataFrame: 模拟的危机数据
        """
        logger.info(f"正在生成{data_points}条模拟危机数据")
        
        # 设置基准日期
        base_date = datetime.now() - pd.Timedelta(days=30)
        
        # 危机类型
        crisis_types = ['产品质量问题', '产品安全事故', '价格争议', '虚假宣传', '服务态度']
        # 内容来源平台
        platforms = ['微博', '知乎', '新闻媒体', '官方网站', '官方微博']
        # 危机关键词
        crisis_keywords = ['质量问题', '缺陷', '投诉', '不满', '失败', '道歉', '召回']
        
        # 生成模拟数据
        data = []
        for i in range(data_points):
            is_crisis = np.random.random() < 0.7  # 70%的内容与危机相关
            data_type = np.random.choice(['news', 'social', 'official'], p=[0.3, 0.6, 0.1])
            
            # 发布时间（在30天内随机分布）
            days_offset = np.random.randint(0, 30)
            published_time = base_date + pd.Timedelta(days=days_offset)
            
            # 情感得分（危机相关内容更偏负面）
            sentiment_score = np.random.normal(-0.3, 0.3) if is_crisis else np.random.normal(0.2, 0.3)
            sentiment_score = max(-1.0, min(1.0, sentiment_score))  # 限制在[-1,1]范围内
            
            data.append({
                'data_type': data_type,
                'title': f"{self.brand_name}相关内容#{i}",
                'content': f"这是关于{self.brand_name}的一条模拟{data_type}内容" + (f"，涉及{np.random.choice(crisis_keywords)}" if is_crisis else ""),
                'source': f"模拟来源{i%10}",
                'published_time': published_time,
                'platform': np.random.choice(platforms),
                'sentiment_score': sentiment_score,
                'crisis_related': 1 if is_crisis else 0,
                'crisis_keyword': np.random.choice(crisis_keywords) if is_crisis else "",
                'brand_name': self.brand_name
            })
        
        # 创建DataFrame
        mock_df = pd.DataFrame(data)
        # 添加日期列
        mock_df['date'] = pd.to_datetime(mock_df['published_time']).dt.date
        
        logger.info(f"已生成{len(mock_df)}条模拟危机数据")
        return mock_df
    
    def load_evaluation_results(self, results_file):
        """
        从Excel文件加载评估结果
        
        Args:
            results_file: 评估结果Excel文件路径
            
        Returns:
            是否成功加载
        """
        try:
            if os.path.exists(results_file):
                results_df = pd.read_excel(results_file)
                
                # 将DataFrame转换为字典格式
                self.evaluation_results = {}
                for _, row in results_df.iterrows():
                    self.evaluation_results[row['评估项目']] = {
                        '评分': row['评分'],
                        '建议': row['建议']
                    }
                
                logger.info(f"从 {results_file} 加载了评估结果")
                return True
            else:
                logger.warning(f"评估结果文件 {results_file} 不存在，将使用模拟数据")
                self.evaluation_results = self.generate_mock_evaluation_results()
                return True
            
        except Exception as e:
            logger.error(f"加载评估结果出错: {str(e)}，将使用模拟数据")
            self.evaluation_results = self.generate_mock_evaluation_results()
            return True
    
    def load_crisis_data(self, data_file):
        """
        加载危机数据
        
        Args:
            data_file: 危机数据Excel文件路径
            
        Returns:
            是否成功加载
        """
        try:
            if os.path.exists(data_file):
                self.crisis_data = pd.read_excel(data_file)
                logger.info(f"从 {data_file} 加载了 {len(self.crisis_data)} 条危机数据")
                return True
            else:
                logger.warning(f"危机数据文件 {data_file} 不存在，将使用模拟数据")
                self.crisis_data = self.generate_mock_crisis_data()
                return True
            
        except Exception as e:
            logger.error(f"加载危机数据出错: {str(e)}，将使用模拟数据")
            self.crisis_data = self.generate_mock_crisis_data()
            return True
    
    def load_failure_cases(self, cases_file=None):
        """
        加载危机失败案例库
        
        Args:
            cases_file: 失败案例JSON文件路径
            
        Returns:
            是否成功加载
        """
        try:
            # 如果提供了文件路径，从文件加载
            if cases_file and os.path.exists(cases_file):
                with open(cases_file, 'r', encoding='utf-8') as f:
                    self.failure_cases = json.load(f)
                logger.info(f"从 {cases_file} 加载了 {len(self.failure_cases)} 个失败案例")
                return True
            
            # 否则，加载内置的默认案例
            self.failure_cases = [
                {
                    "brand": "蒙牛",
                    "industry": "食品饮料",
                    "crisis_type": "产品质量",
                    "description": "2008年三聚氰胺事件，蒙牛产品被检出含有三聚氰胺",
                    "failure_points": ["危机预警系统缺失", "质量监控不严", "应对不及时", "沟通不透明"],
                    "consequences": ["品牌形象严重受损", "销量下跌", "经济损失", "消费者信任丧失"],
                    "lessons": ["建立严格的质量监控体系", "建立危机预警机制", "制定危机应对预案", "保持透明沟通"]
                },
                {
                    "brand": "三星",
                    "industry": "电子科技",
                    "crisis_type": "产品安全",
                    "description": "2016年Galaxy Note 7电池爆炸事件",
                    "failure_points": ["质量控制不严", "应对决策拖延", "召回行动混乱", "危机扩大化"],
                    "consequences": ["品牌形象受损", "巨额经济损失", "市场份额下降"],
                    "lessons": ["强化产品安全测试", "快速决策响应机制", "完善召回流程", "透明沟通策略"]
                },
                {
                    "brand": "优衣库",
                    "industry": "服装零售",
                    "crisis_type": "公共关系",
                    "description": "2015年试衣间不雅视频事件",
                    "failure_points": ["危机应对不及时", "公关声明模糊", "社交媒体管控不足"],
                    "consequences": ["舆论危机", "店铺客流减少", "品牌形象负面"],
                    "lessons": ["建立社交媒体监测系统", "完善店内安全管理", "制定明确危机沟通策略"]
                },
                {
                    "brand": "滴滴",
                    "industry": "出行服务",
                    "crisis_type": "安全事故",
                    "description": "2018年顺风车安全事件",
                    "failure_points": ["安全体系不完善", "客诉处理不及时", "危机响应滞后", "公关措施不当"],
                    "consequences": ["政府监管加强", "业务暂停", "用户流失", "品牌信任崩塌"],
                    "lessons": ["建立完善的安全预警机制", "强化客诉快速响应", "危机沟通培训", "建立长效安全体系"]
                },
                {
                    "brand": "瑞幸咖啡",
                    "industry": "餐饮零售",
                    "crisis_type": "财务造假",
                    "description": "2020年财务造假事件",
                    "failure_points": ["公司治理缺失", "内部监控失效", "危机处理不当"],
                    "consequences": ["股价暴跌", "退市", "高管法律责任", "品牌信誉受损"],
                    "lessons": ["健全企业治理", "强化内部审计", "坚持诚信经营", "透明信息披露"]
                },
                # 特斯拉相关案例
                {
                    "brand": "特斯拉",
                    "industry": "汽车制造",
                    "crisis_type": "产品安全事故",
                    "description": "2021年特斯拉刹车失灵事件，多位车主反映行驶过程中出现刹车失灵",
                    "failure_points": ["危机沟通策略失误", "公关态度强硬", "社交媒体回应不当", "技术分析不透明"],
                    "consequences": ["用户信任下降", "舆论持续发酵", "销量受影响", "监管部门介入调查"],
                    "lessons": ["避免过度防御态度", "重视用户投诉与体验", "提高技术沟通透明度", "建立专业危机公关团队"]
                },
                {
                    "brand": "特斯拉",
                    "industry": "汽车制造",
                    "crisis_type": "自动驾驶安全",
                    "description": "2018-2020年间多起Autopilot相关交通事故，引发对自动驾驶安全性的质疑",
                    "failure_points": ["功能宣传与实际能力不符", "用户警示不足", "责任推卸倾向", "数据分析不透明"],
                    "consequences": ["安全担忧加剧", "政府监管加强", "品牌形象两极化", "法律诉讼增加"],
                    "lessons": ["明确技术能力边界", "加强用户教育", "主动发布安全数据", "建立事故快速响应机制"]
                },
                {
                    "brand": "特斯拉",
                    "industry": "汽车制造",
                    "crisis_type": "电池安全",
                    "description": "多起特斯拉电池起火事件，引发对电动车安全性的担忧",
                    "failure_points": ["电池安全设计不足", "热失控预防机制不完善", "事故处理标准化不足", "用户安全培训不到位"],
                    "consequences": ["媒体广泛报道", "消费者恐慌", "监管审查增加", "竞争对手借机攻击"],
                    "lessons": ["加强电池安全设计", "优化热管理系统", "建立详细事故处理流程", "提高用户安全意识培训"]
                },
                # 其他汽车品牌案例
                {
                    "brand": "大众",
                    "industry": "汽车制造",
                    "crisis_type": "排放作弊",
                    "description": "2015年'排放门'事件，大众在柴油车上安装作弊软件以通过排放测试",
                    "failure_points": ["企业诚信缺失", "内部监管失效", "危机处理拖延", "公关策略失误"],
                    "consequences": ["巨额罚款", "股价暴跌", "全球召回", "品牌形象严重受损"],
                    "lessons": ["建立严格的合规文化", "强化内部监督机制", "及时承认错误并道歉", "透明公开的危机处理"]
                },
                {
                    "brand": "丰田",
                    "industry": "汽车制造",
                    "crisis_type": "刹车系统故障",
                    "description": "2009-2010年丰田加速门事件，多起车辆失控事故",
                    "failure_points": ["技术问题处理不及时", "初期危机轻视", "信息披露不足", "全球协调不足"],
                    "consequences": ["大规模召回", "销量下滑", "股价下跌", "美国国会听证"],
                    "lessons": ["快速响应用户投诉", "全球统一危机应对", "提高供应链质量控制", "建立透明沟通机制"]
                },
                {
                    "brand": "通用汽车",
                    "industry": "汽车制造",
                    "crisis_type": "点火开关故障",
                    "description": "2014年通用汽车点火开关故障事件，导致多起致命事故",
                    "failure_points": ["长期忽视安全隐患", "内部信息传递断裂", "延迟召回决策", "公司文化问题"],
                    "consequences": ["大规模召回", "高额赔偿", "政府调查", "公众信任受损"],
                    "lessons": ["建立安全优先文化", "完善内部问题上报机制", "提高召回决策效率", "重组安全管理体系"]
                },
                {
                    "brand": "小米",
                    "industry": "电子科技",
                    "crisis_type": "产品质量",
                    "description": "2016年小米手机发热问题，多用户反映手机严重发热甚至烫伤",
                    "failure_points": ["硬件设计不完善", "测试不充分", "初期回应模糊", "用户沟通不足"],
                    "consequences": ["负面评价增加", "销量影响", "竞品趁机攻击", "用户流失"],
                    "lessons": ["加强极端使用场景测试", "建立快速响应用户反馈机制", "增强产品热管理设计", "改进技术沟通策略"]
                },
                {
                    "brand": "小米",
                    "industry": "电子科技",
                    "crisis_type": "隐私安全",
                    "description": "2019年浏览器隐私数据收集争议，被曝秘密收集用户浏览数据",
                    "failure_points": ["隐私政策不透明", "用户数据保护不足", "危机沟通不专业", "技术与伦理平衡失调"],
                    "consequences": ["用户信任下降", "媒体负面报道", "监管关注", "竞争对手抨击"],
                    "lessons": ["提高隐私政策透明度", "改进用户数据收集机制", "加强安全与隐私保护", "重视伦理问题"]
                }
            ]
            
            # 检查是否需要特定品牌的案例
            brand_specific_cases = []
            if self.brand_name:
                brand_lower = self.brand_name.lower()
                # 特斯拉特定案例更多细节
                if "特斯拉" in brand_lower or "tesla" in brand_lower:
                    brand_specific_cases = [
                        {
                            "brand": "特斯拉",
                            "industry": "汽车制造",
                            "crisis_type": "维权事件",
                            "description": "2021年上海车展特斯拉车顶维权事件，车主因刹车失灵问题维权引发全国关注",
                            "failure_points": ["公关回应过于强硬", "危机沟通策略失误", "用户投诉处理机制不完善", "舆情应对不及时", "态度不够谦虚"],
                            "consequences": ["全国舆论发酵", "监管部门约谈", "销量下滑", "品牌形象受损", "维权行为增加"],
                            "lessons": ["危机公关需更加谦虚", "重视每一位用户投诉", "建立专业维权处理机制", "提高技术问题透明度", "培训员工正确沟通态度"]
                        },
                        {
                            "brand": "特斯拉",
                            "industry": "汽车制造",
                            "crisis_type": "突然降价",
                            "description": "2022年末至2023年初特斯拉大幅降价事件，引发老车主不满和集体维权",
                            "failure_points": ["价格策略沟通不足", "忽视老客户感受", "缺乏过渡期安排", "补偿措施不到位"],
                            "consequences": ["老客户强烈不满", "维权活动增加", "转介绍率下降", "品牌忠诚度受损"],
                            "lessons": ["价格调整前做好沟通", "设置合理过渡期", "为老用户提供专属权益", "建立健全的客户关系管理体系"]
                        },
                        {
                            "brand": "特斯拉",
                            "industry": "汽车制造",
                            "crisis_type": "首席执行官言论",
                            "description": "多次因马斯克在社交媒体上的言论导致公司股价波动和品牌争议",
                            "failure_points": ["高管言行管理缺失", "企业与个人形象边界模糊", "社交媒体风险意识不足", "危机预警机制不健全"],
                            "consequences": ["股价大幅波动", "品牌争议增加", "分散管理层注意力", "监管机构调查"],
                            "lessons": ["建立高管社交媒体规范", "区分个人与公司声明", "强化合规审核机制", "构建多层次企业发言人体系"]
                        }
                    ]
                # 小米特定案例更多细节
                elif "小米" in brand_lower or "xiaomi" in brand_lower:
                    brand_specific_cases = [
                        {
                            "brand": "小米",
                            "industry": "电子科技",
                            "crisis_type": "供货能力",
                            "description": "2020年小米11发布后因供货不足引发'饥饿营销'质疑",
                            "failure_points": ["产能规划不足", "营销与供应链协调不够", "消费者预期管理不当", "舆情监测不及时"],
                            "consequences": ["消费者不满情绪高涨", "竞品趁机攻击", "品牌信任受损", "销售转化率下降"],
                            "lessons": ["加强产能与营销协同", "提高库存与需求预测准确性", "设置合理的消费者预期", "改进线上线下库存协调"]
                        },
                        {
                            "brand": "小米",
                            "industry": "电子科技",
                            "crisis_type": "系统广告争议",
                            "description": "MIUI系统内置广告过多引发用户不满",
                            "failure_points": ["商业模式与用户体验失衡", "广告投放不够精准", "用户反馈机制不完善", "产品决策偏离用户需求"],
                            "consequences": ["用户体验下降", "品牌口碑受损", "老用户流失", "社交媒体负面讨论增加"],
                            "lessons": ["平衡商业利益与用户体验", "提供广告控制选项", "建立用户参与产品决策机制", "定期评估用户满意度"]
                        }
                    ]
                
                # 将特定品牌的案例添加到案例库
                if brand_specific_cases:
                    self.failure_cases.extend(brand_specific_cases)
            
            logger.info(f"加载了 {len(self.failure_cases)} 个内置失败案例")
            return True
            
        except Exception as e:
            logger.error(f"加载失败案例出错: {str(e)}")
            return False
    
    def analyze_crisis_patterns(self):
        """
        分析危机模式
        
        Returns:
            危机模式分析结果
        """
        if self.crisis_data is None or self.crisis_data.empty:
            logger.error("未加载危机数据，无法分析危机模式")
            return None
        
        try:
            # 提取危机相关内容
            crisis_content = self.crisis_data[self.crisis_data['crisis_related'] == 1]
            
            if crisis_content.empty:
                logger.warning("未发现危机相关内容，无法分析模式")
                return None
            
            # 根据数据类型分析不同来源的危机信息
            source_distribution = crisis_content['data_type'].value_counts().to_dict()
            
            # 分析危机关键词
            keywords = Counter()
            for keyword in crisis_content['crisis_keyword'].dropna():
                keywords[keyword] += 1
            
            # 分析危机时间分布
            if 'published_time' in crisis_content.columns:
                crisis_content['date'] = pd.to_datetime(crisis_content['published_time']).dt.date
                time_distribution = crisis_content['date'].value_counts().sort_index().to_dict()
            else:
                time_distribution = {}
            
            # 分析情感走势
            sentiment_by_source = crisis_content.groupby('data_type')['sentiment_score'].mean().to_dict()
            
            # 提取危机类型模式（基于关键词和内容分析）
            crisis_types = self._identify_crisis_types(crisis_content)
            
            return {
                'source_distribution': source_distribution,
                'keywords': dict(keywords.most_common(10)),
                'time_distribution': time_distribution,
                'sentiment_by_source': sentiment_by_source,
                'crisis_types': crisis_types
            }
            
        except Exception as e:
            logger.error(f"分析危机模式出错: {str(e)}")
            return None
    
    def _identify_crisis_types(self, crisis_data):
        """
        识别危机类型
        
        Args:
            crisis_data: 危机相关数据
            
        Returns:
            危机类型及其可能性
        """
        # 危机类型及其关键词
        crisis_type_keywords = {
            '产品质量问题': ['质量', '故障', '缺陷', '不良', '差', '坏', '问题'],
            '产品安全事故': ['安全', '事故', '爆炸', '起火', '受伤', '危险'],
            '价格争议': ['价格', '贵', '涨价', '降价', '促销', '退款'],
            '虚假宣传': ['虚假', '造假', '欺骗', '宣传', '广告', '误导'],
            '服务态度': ['服务', '态度', '差', '傲慢', '客服', '投诉'],
            '食品安全': ['食品', '安全', '卫生', '添加剂', '过期', '变质'],
            '数据泄露': ['数据', '泄露', '隐私', '信息', '安全', '黑客'],
            '企业形象': ['形象', '声誉', '丑闻', '负面', '公关', '舆论'],
            '劳资纠纷': ['员工', '工人', '劳资', '纠纷', '罢工', '抗议'],
            '环境问题': ['环境', '污染', '排放', '绿色', '可持续', '生态']
        }
        
        # 初始化结果
        crisis_types = defaultdict(int)
        
        # 遍历所有内容
        for content in crisis_data['content'].dropna():
            if not isinstance(content, str):
                continue
                
            # 检查每种危机类型的关键词
            for crisis_type, keywords in crisis_type_keywords.items():
                match_count = sum([1 for keyword in keywords if keyword in content])
                if match_count > 0:
                    crisis_types[crisis_type] += match_count
        
        # 标准化结果
        total = sum(crisis_types.values())
        if total > 0:
            normalized_types = {k: round(v/total, 2) for k, v in crisis_types.items()}
            return dict(sorted(normalized_types.items(), key=lambda x: x[1], reverse=True))
        
        return {}
    
    def find_similar_failure_cases(self, top_n=3):
        """
        寻找相似的失败案例
        
        Args:
            top_n: 返回的相似案例数量
            
        Returns:
            相似的失败案例列表
        """
        if not self.failure_cases:
            logger.error("未加载失败案例库，无法查找相似案例")
            return []
        
        if self.crisis_data is None or self.crisis_data.empty:
            logger.error("未加载危机数据，无法查找相似案例")
            return []
        
        try:
            # 分析当前危机模式
            crisis_patterns = self.analyze_crisis_patterns()
            if not crisis_patterns:
                return []
            
            # 当前危机的主要类型
            current_crisis_types = list(crisis_patterns['crisis_types'].keys())
            if not current_crisis_types:
                current_crisis_types = ["未知类型"]
            
            # 当前危机的关键词
            current_keywords = list(crisis_patterns['keywords'].keys())
            
            # 计算与每个案例的相似度
            similarity_scores = []
            
            for case in self.failure_cases:
                score = 0
                
                # 行业相似度
                if 'industry' in case and self.brand_name:
                    # 这里可以添加行业分类逻辑
                    pass
                
                # 危机类型相似度
                if 'crisis_type' in case:
                    for ctype in current_crisis_types:
                        if ctype.lower() in case['crisis_type'].lower() or case['crisis_type'].lower() in ctype.lower():
                            score += 3
                
                # 关键词相似度
                if 'description' in case:
                    for keyword in current_keywords:
                        if keyword in case['description'].lower():
                            score += 1
                
                # 失败点相似度（基于评估结果）
                if 'failure_points' in case and self.evaluation_results:
                    for point in case['failure_points']:
                        for key, value in self.evaluation_results.items():
                            if isinstance(value, dict) and '评分' in value and value['评分'] < 3:
                                if any(keyword in point.lower() for keyword in key.lower().split()):
                                    score += 2
                
                similarity_scores.append((case, score))
            
            # 按相似度降序排序并返回前top_n个案例
            sorted_cases = sorted(similarity_scores, key=lambda x: x[1], reverse=True)
            return [case for case, score in sorted_cases[:top_n]]
            
        except Exception as e:
            logger.error(f"查找相似失败案例出错: {str(e)}")
            return []
    
    def generate_prevention_mechanism(self):
        """
        生成预防机制建议
        
        Returns:
            预防机制建议字典
        """
        try:
            # 初始化预防机制建议
            prevention_mechanism = {
                'brand': self.brand_name,
                'generation_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'crisis_overview': {},
                'prevention_systems': [],
                'monitoring_mechanisms': [],
                'response_protocols': [],
                'training_recommendations': [],
                'communication_strategies': [],
                'similar_cases': []
            }
            
            # 分析危机模式
            crisis_patterns = self.analyze_crisis_patterns()
            if crisis_patterns:
                prevention_mechanism['crisis_overview'] = {
                    'main_crisis_types': list(crisis_patterns['crisis_types'].keys())[:3],
                    'key_keywords': list(crisis_patterns['keywords'].keys())[:5]
                }
            
            # 查找相似失败案例
            similar_cases = self.find_similar_failure_cases()
            if similar_cases:
                # 提取失败案例中的教训
                for case in similar_cases:
                    if 'lessons' in case:
                        for lesson in case['lessons']:
                            # 根据教训内容分类到不同的预防机制类型
                            if any(keyword in lesson.lower() for keyword in ['监测', '预警', '监控', '跟踪']):
                                prevention_mechanism['monitoring_mechanisms'].append(lesson)
                            elif any(keyword in lesson.lower() for keyword in ['培训', '教育', '学习']):
                                prevention_mechanism['training_recommendations'].append(lesson)
                            elif any(keyword in lesson.lower() for keyword in ['沟通', '声明', '公关']):
                                prevention_mechanism['communication_strategies'].append(lesson)
                            elif any(keyword in lesson.lower() for keyword in ['响应', '应对', '预案']):
                                prevention_mechanism['response_protocols'].append(lesson)
                            else:
                                prevention_mechanism['prevention_systems'].append(lesson)
                
                # 保存相似案例概述
                prevention_mechanism['similar_cases'] = [
                    {
                        'brand': case.get('brand', ''),
                        'crisis_type': case.get('crisis_type', ''),
                        'description': case.get('description', '')
                    }
                    for case in similar_cases
                ]
            
            # 根据评估结果添加建议
            if self.evaluation_results:
                for key, value in self.evaluation_results.items():
                    if isinstance(value, dict) and '建议' in value:
                        recommendation = value['建议']
                        
                        if '响应速度' in key:
                            prevention_mechanism['response_protocols'].append(
                                f"建立快速响应机制: {recommendation}"
                            )
                        elif '透明度' in key:
                            prevention_mechanism['communication_strategies'].append(
                                f"提高沟通透明度: {recommendation}"
                            )
                        elif '品牌形象' in key:
                            prevention_mechanism['prevention_systems'].append(
                                f"保护品牌形象: {recommendation}"
                            )
            
            # 添加通用预防机制建议
            self._add_general_prevention_recommendations(prevention_mechanism)
            
            # 去重
            for key in prevention_mechanism:
                if isinstance(prevention_mechanism[key], list):
                    prevention_mechanism[key] = list(set(prevention_mechanism[key]))
            
            return prevention_mechanism
            
        except Exception as e:
            logger.error(f"生成预防机制建议出错: {str(e)}")
            return None
    
    def _add_general_prevention_recommendations(self, prevention_mechanism):
        """
        添加通用预防机制建议
        
        Args:
            prevention_mechanism: 预防机制建议字典
        """
        # 监控机制
        if not prevention_mechanism['monitoring_mechanisms']:
            prevention_mechanism['monitoring_mechanisms'] = [
                "建立社交媒体和新闻舆情监测系统，实时跟踪品牌相关内容",
                "设置关键词预警，对潜在负面信息进行早期识别",
                "定期分析用户评价和投诉，识别潜在问题",
                "建立竞品监测机制，了解行业危机事件"
            ]
        
        # 响应协议
        if not prevention_mechanism['response_protocols']:
            prevention_mechanism['response_protocols'] = [
                "制定分级危机响应预案，明确不同级别危机的处理流程",
                "建立危机处理小组，明确职责分工和决策链",
                "设定响应时间标准，确保在危机爆发后及时回应",
                "准备常见危机应对话术模板，便于快速响应"
            ]
        
        # 培训建议
        if not prevention_mechanism['training_recommendations']:
            prevention_mechanism['training_recommendations'] = [
                "定期进行危机沟通培训，提高团队应对能力",
                "模拟危机演练，检验危机响应预案的有效性",
                "媒体应对技巧培训，提高发言人表现",
                "客户服务培训，提高一线员工危机识别和处理能力"
            ]
        
        # 沟通策略
        if not prevention_mechanism['communication_strategies']:
            prevention_mechanism['communication_strategies'] = [
                "建立透明沟通原则，保持信息公开和真实",
                "多渠道沟通策略，确保信息传达到所有利益相关方",
                "制定社交媒体沟通指南，规范危机期间的社媒发布",
                "建立媒体关系，为危机沟通创造良好外部环境"
            ]
        
        # 预防系统
        if not prevention_mechanism['prevention_systems']:
            prevention_mechanism['prevention_systems'] = [
                "建立品牌风险评估制度，定期审视潜在风险点",
                "完善产品质量控制体系，减少质量问题引发的危机",
                "加强内部合规管理，防范违规行为导致的公关危机",
                "建立顾客反馈收集和分析系统，及时解决用户不满"
            ]
    
    def generate_prevention_report(self, output_file='brand_crisis_prevention_report.xlsx'):
        """
        生成预防机制报告
        
        Args:
            output_file: 输出Excel文件路径
            
        Returns:
            是否成功生成报告
        """
        try:
            # 生成预防机制建议
            prevention_mechanism = self.generate_prevention_mechanism()
            if not prevention_mechanism:
                return False
            
            # 创建Excel文件
            writer = pd.ExcelWriter(output_file, engine='openpyxl')
            
            # 危机概览
            overview_data = {
                '品牌': [prevention_mechanism['brand']],
                '生成时间': [prevention_mechanism['generation_time']]
            }
            
            if prevention_mechanism['crisis_overview']:
                overview_data['主要危机类型'] = [', '.join(prevention_mechanism['crisis_overview'].get('main_crisis_types', []))]
                overview_data['关键词'] = [', '.join(prevention_mechanism['crisis_overview'].get('key_keywords', []))]
            
            overview_df = pd.DataFrame(overview_data)
            overview_df.to_excel(writer, sheet_name='危机概览', index=False)
            
            # 预防系统建议
            prevention_systems_df = pd.DataFrame({
                '预防系统建议': prevention_mechanism['prevention_systems']
            })
            prevention_systems_df.to_excel(writer, sheet_name='预防系统', index=False)
            
            # 监控机制建议
            monitoring_df = pd.DataFrame({
                '监控机制建议': prevention_mechanism['monitoring_mechanisms']
            })
            monitoring_df.to_excel(writer, sheet_name='监控机制', index=False)
            
            # 响应协议建议
            response_df = pd.DataFrame({
                '响应协议建议': prevention_mechanism['response_protocols']
            })
            response_df.to_excel(writer, sheet_name='响应协议', index=False)
            
            # 培训建议
            training_df = pd.DataFrame({
                '培训建议': prevention_mechanism['training_recommendations']
            })
            training_df.to_excel(writer, sheet_name='培训建议', index=False)
            
            # 沟通策略建议
            communication_df = pd.DataFrame({
                '沟通策略建议': prevention_mechanism['communication_strategies']
            })
            communication_df.to_excel(writer, sheet_name='沟通策略', index=False)
            
            # 相似案例
            if prevention_mechanism['similar_cases']:
                similar_cases_df = pd.DataFrame(prevention_mechanism['similar_cases'])
                similar_cases_df.to_excel(writer, sheet_name='相似案例', index=False)
            
            # 保存Excel文件
            writer.close()
            
            logger.info(f"预防机制报告已保存到 {output_file}")
            return True
            
        except Exception as e:
            logger.error(f"生成预防机制报告出错: {str(e)}")
            return False
    
    def generate_crisis_radar_plot(self, output_file='crisis_radar.png'):
        """
        生成危机雷达图
        
        Args:
            output_file: 输出文件路径
            
        Returns:
            是否成功生成图表
        """
        if not self.evaluation_results:
            logger.error("未加载评估结果，无法生成雷达图")
            return False
        
        try:
            # 提取评分
            categories = []
            scores = []
            
            for key, value in self.evaluation_results.items():
                if isinstance(value, dict) and '评分' in value:
                    if key not in ['综合得分', '总体评估']:  # 排除综合评分
                        categories.append(key)
                        scores.append(value['评分'])
            
            if not categories:
                logger.error("未找到评分数据，无法生成雷达图")
                return False
            
            # 计算雷达图的角度
            angles = np.linspace(0, 2*np.pi, len(categories), endpoint=False).tolist()
            scores.append(scores[0])  # 闭合雷达图
            angles.append(angles[0])  # 闭合雷达图
            categories.append(categories[0])  # 闭合标签
            
            # 创建图表
            fig, ax = plt.subplots(figsize=(10, 8), subplot_kw=dict(polar=True))
            
            # 绘制雷达图
            ax.plot(angles, scores, 'o-', linewidth=2, label=self.brand_name)
            ax.fill(angles, scores, alpha=0.25)
            
            # 设置刻度和标签
            ax.set_thetagrids(np.degrees(angles), categories)
            ax.set_ylim(0, 5)
            ax.set_yticks([1, 2, 3, 4, 5])
            ax.set_yticklabels(['1', '2', '3', '4', '5'])
            ax.grid(True)
            
            # 添加标题
            plt.title(f"{self.brand_name} 危机处理能力雷达图", size=15, y=1.1)
            
            # 保存图表
            plt.tight_layout()
            plt.savefig(output_file)
            plt.close()
            
            logger.info(f"危机雷达图已保存到 {output_file}")
            return True
            
        except Exception as e:
            logger.error(f"生成危机雷达图出错: {str(e)}")
            return False
    
    def generate_keyword_cloud(self, output_file='crisis_keywords.png'):
        """
        生成危机关键词云图
        
        Args:
            output_file: 输出文件路径
            
        Returns:
            是否成功生成图表
        """
        if self.crisis_data is None or self.crisis_data.empty:
            logger.error("未加载危机数据，无法生成关键词云图")
            return False
        
        try:
            # 分析危机模式
            crisis_patterns = self.analyze_crisis_patterns()
            if not crisis_patterns or not crisis_patterns['keywords']:
                logger.error("未找到关键词数据，无法生成词云图")
                return False
            
            # 准备词云数据
            keywords = crisis_patterns['keywords']
            
            # 创建词云
            wordcloud = WordCloud(
                width=800,
                height=500,
                background_color='white',
                max_words=100,
                max_font_size=100,
                relative_scaling=0.5,
                normalize_plurals=False,
                font_path='simhei.ttf' if os.path.exists('simhei.ttf') else None
            ).generate_from_frequencies(keywords)
            
            # 创建图表
            plt.figure(figsize=(10, 8))
            plt.imshow(wordcloud, interpolation='bilinear')
            plt.axis('off')
            plt.tight_layout()
            
            # 保存图表
            plt.savefig(output_file)
            plt.close()
            
            logger.info(f"危机关键词云图已保存到 {output_file}")
            return True
            
        except Exception as e:
            logger.error(f"生成关键词云图出错: {str(e)}")
            return False

if __name__ == "__main__":
    # 测试代码
    generator = PreventionGenerator("小米")
    
    # 加载评估结果
    generator.load_evaluation_results("output/小米_crisis_evaluation_report.xlsx")
    
    # 加载危机数据
    generator.load_crisis_data("output/小米_integrated_crisis_data.xlsx")
    
    # 加载失败案例库
    generator.load_failure_cases()
    
    # 分析危机模式
    patterns = generator.analyze_crisis_patterns()
    if patterns:
        print("危机主要类型:", patterns['crisis_types'])
        print("危机关键词:", patterns['keywords'])
    
    # 生成预防机制建议
    prevention = generator.generate_prevention_mechanism()
    if prevention:
        print("预防系统建议:", prevention['prevention_systems'])
        print("沟通策略建议:", prevention['communication_strategies'])
    
    # 生成预防机制报告
    generator.generate_prevention_report("output/小米_crisis_prevention_report.xlsx")
    
    # 生成危机雷达图
    generator.generate_crisis_radar_plot("output/小米_crisis_radar.png")
    
    # 生成危机关键词云图
    generator.generate_keyword_cloud("output/小米_crisis_keywords.png") 